package com.lqq.chapter03.lock;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @Author lqq677
 * @Date 2021/8/9 22:04
 * @Description 线程通信，演示虚假唤醒
 */

//资源类
class Noodles {
    //面的数量
    private int num = 0;
    //可重入锁
    private Lock lock = new ReentrantLock();
    private Condition condition = lock.newCondition();


    //厨师做面的方法
    public  void incr() throws InterruptedException {
        //获取锁
          lock.lock();
           try {
               //判断，如果面的数量为1，则等待食客吃完面再做面
               while (num == 1) {
                   //等待
                   condition.await();
               }
               //干活 +1
               num++;
               System.out.println(Thread.currentThread().getName()+"做好了一份面，当前有"+num+"份面");
               //通知顾客吃面
               condition.signalAll();

          }catch (Exception e){
              e.printStackTrace();
          }finally {
              lock.unlock();
          }

    }

    //顾客吃面的方法
    public void decr() throws InterruptedException {
         lock.lock();
          try {
              //判断，如果面的数量为0，则等待厨师做完面再吃面
              while (num == 0) {
                  //等待
                  condition.await();
              }
              //干活 顾客吃面
              num--;
              System.out.println(Thread.currentThread().getName()+"吃了一份面，当前有"+num+"份面");
              //通知厨师做面
              condition.signalAll();

         }catch (Exception e){
             e.printStackTrace();
         }finally {
             lock.unlock();
         }
    }

}


public class ThreadDemo {
    public static void main(String[] args) {

        Noodles noodles = new Noodles();

        //+1线程 厨师A做面
        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {
                    noodles.incr();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
                }, "厨师A").start();

        //-1线程 顾客甲吃面
        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {
                    noodles.decr();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "顾客甲").start();

    }
}
